﻿#define _CRT_SECURE_NO_WARNINGS

//OJ练习题
//26.
//给你两个整数 num1 和 num2 ，返回这两个整数的和
int sum(int num1, int num2) {
	return num1 + num2;
}

//27.
//⼩A 和 ⼩B 在玩猜数字。⼩B 每次从 1, 2, 3 中随机选择⼀个，⼩A 每次也从 1, 2, 3 中选
//择⼀个猜。他们⼀共进⾏三次这个游戏，请返回 ⼩A 猜对了⼏次？
//输⼊的guess数组为 ⼩A 每次的猜测， answer 数组为 ⼩B 每次的选择。 guess 和 answer 的⻓度
//都等于3。
int game(int* guess, int guessSize, int* answer, int answerSize) {
    int count = 0;
    int i;
    for (i = 0; i < guessSize; i++)
    {
        if (guess[i] == answer[i])
            count++;
    }
    return count;
}

//28.
//给你⼀个四舍五⼊到两位⼩数的⾮负浮点数 celsius 来表⽰温度，以 摄⽒度（Celsius）为单位。
//你需要将摄⽒度转换为 开⽒度（Kelvin）和 华⽒度（Fahrenheit），并以数组 ans = [kelvin,
//fahrenheit] 的形式返回结果。
//返回数组 ans 。与实际答案误差不超过 10 - 5 的会视为正确答案。
double* convertTemperature(double celsius, int* returnSize) {
    //开辟动态数组
    double* ans = (double*)malloc(sizeof(double) * 2);
    double Kelvin = celsius + 273.15;
    double Fahrenheit = celsius * 1.80 + 32.00;


    ans[0] = Kelvin;
    ans[1] = Fahrenheit;
    *returnSize = 2;
    return ans;
}


//29.
//给你⼀个正整数 n ，返回 2 和 n 的最⼩公倍数（正整数)
int smallestEvenMultiple(int n) {
    //每个偶数和2的最⼩公倍数是⾃⾝，每个奇数和2的最⼩公倍数是⾃⾝的⼆倍。
    if (n % 2 == 0)
        return n;
    return 2 * n;
}

//30.
//给你两个整数， n 和 start 。
//数组 nums 定义为： nums[i] = start + 2 * i （下标从 0 开始）且 n == nums.length.
//请返回 nums 中所有元素按位异或（XOR）后得到的结果。
int xorOperation(int n, int start) {
    // 存入数据
    //int* nums = malloc(sizeof(int) * n);
    int nums[n];
    int i = 0;
    for (i = 0; i < n; i++) {
        nums[i] = start + 2 * i;
    }
    int sum = 0;
    for (i = 0; i < n; i++) {
        sum = sum ^ nums[i];
    }
    return sum;
}


//31.
//给你⼀个正整数数组 nums 。
//元素和 是 nums 中的所有元素相加求和。
//数字和 是 nums 中每⼀个元素的每⼀数位（重复数位需多次求和）相加求和。
//返回 元素和 与 数字和 的绝对差。
//注意：两个整数 x 和 y 的绝对差定义为 |x-y|
int differenceOfSum(int* nums, int numsSize) {
    int i;
    int elemsum = 0;//元素和
    int numsum = 0;//数字和
    for (i = 0; i < numsSize; i++)
    {
        elemsum = elemsum + nums[i];
        while (nums[i])
        {
            numsum += nums[i] % 10;
            nums[i] /= 10;
        }
    }

    return abs(elemsum - numsum);
}

//32.
//给你⼀个整数 x ，如果 x 是⼀个回⽂整数，返回 true ；否则，返回 false 。
//回⽂数是指正序（从左向右）和倒序（从右向左）读都是⼀样的整数。
//例如，121 是回⽂，⽽ 123 不是。
bool isPalindrome(int x) {
    // 负数一定不是回文数
    if (x < 0)
        return false;
    int temp = x;
    long long n = 0;
    while (temp) {
        n = n * 10 + temp % 10;
        temp /= 10;
    }
    if (n == x)
        return true;
    return false;
}

//33.
//给你⼀个数组  nums ，对于其中每个元素 nums[i] ，请你统计数组中⽐它⼩的所有数字的数⽬。
//换⽽⾔之，对于每个  nums[i] 你必须计算出有效的 j  的数量，其中 j 满⾜  j != i 且
//nums[j] < nums[i] 。
//以数组形式返回答案。

//暴力求解
int* smallerNumbersThanCurrent(int* nums, int numsSize, int* returnSize) {
    int* a = (int*)malloc(sizeof(int) * numsSize);
    int i;
    int j;
    int count;
    for (i = 0; i < numsSize; i++) {
        count = 0;
        for (j = 0; j < numsSize; j++) {
            if (nums[i] > nums[j])
                count++;
        }
        a[i] = count;
    }
    *returnSize = numsSize;
    return a;
}

//先排序在二分查找
// 二分查找
int BinarySearch(int* a, int numsSize, int num) {
    int left = 0;
    int right = numsSize - 1;
    while (left < right) {

        int mid = (left + right) / 2;
        // num在mid左边
        if (a[mid] < num) {
            left = mid + 1;
        }
        else
            right = mid;
    }
    // 循环结束还没找到
    return left;
}
int* smallerNumbersThanCurrent(int* nums, int numsSize, int* returnSize) {
    // 定义有序数组
    int* order = (int*)malloc(sizeof(int) * numsSize);
    // 定义存储答案的数组
    int* ans = (int*)malloc(sizeof(int) * numsSize);
    int i;
    // 将原数组添加到有序数组中
    for (i = 0; i < numsSize; i++)
        order[i] = nums[i];
    int j;
    // 排序将order中的数组变为有序数组
    for (i = 0; i < numsSize - 1; i++) {
        for (j = i + 1; j < numsSize; j++) {
            if (order[i] > order[j]) {
                int temp = order[i];
                order[i] = order[j];
                order[j] = temp;
            }
        }
    }

    // 循坏遍历原来的每个一数，找到排序后所对应的索引
    for (i = 0; i < numsSize; i++) {
        ans[i] = BinarySearch(order, numsSize, nums[i]);
    }
    *returnSize = numsSize;
    return ans;
}


//34
//给你⼀个字符串 s 和⼀个字符 letter ，返回在 s 中等于  letter 字符所占的 百分⽐ ，向下
//取整到最接近的百分⽐。
int percentageLetter(char* s, char letter) {
    int len = strlen(s);
    int i;
    int count = 0;
    for (i = 0; i < len; i++)
    {
        if (s[i] == letter)
            count++;
    }

    int percent = (int)(count / (len * 1.0) * 100);
    return percent;
}

//35
//给你⼀个有效的 IPv4 地址 address ，返回这个 IP 地址的⽆效化版本。
//所谓⽆效化 IP 地址，其实就是⽤ "[.]" 代替了每个 "."。
char* defangIPaddr(char* address) {
    int len = strlen(address);
    char* a = (char*)malloc(sizeof(char) * (len + 7));
    int i;
    int j = 0;
    for (i = 0; i < len; i++)
    {
        if (address[i] == '.')
        {
            a[j++] = '[';
            a[j++] = '.';
            a[j++] = ']';
        }
        else
        {
            a[j++] = address[i];
        }
    }
    a[j] = '\0';
    return a;
}

//36
//⼀个 句⼦由⼀些单词以及它们之间的单个空格组成，句⼦的开头和结尾不会有多余空格。
//给你⼀个字符串数组sentences ，其中 sentences[i]表⽰单个 句⼦ 。
int mostWordsFound(char** sentences, int sentencesSize) {
    // 思路：比较每个句子空格数量
    int a[sentencesSize];
    int i;
    int j;
    int count;
    // 先获取每一个句子
    for (i = 0; i < sentencesSize; i++) {
        count = 0;
        // 遍历每一个句子中每一个元素
        int len = strlen(sentences[i]);
        for (j = 0; j < len; j++) {
            if (sentences[i][j] == ' ')
                count++;
        }
        a[i] = count;
    }

    int max = a[0];
    for (i = 1; i < sentencesSize; i++) {
        if (a[i] > max)
            max = a[i];
    }
    return max + 1;
}